Virtual TPM persistent states contain VTPM secrets, which are encrypted
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 30 Dec 2005 10:31:12 +0000 (11:31 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Fri, 30 Dec 2005 10:31:12 +0000 (11:31 +0100)
using symmetric keys and stored on disk along with those symmetric keys.
The attached patch uses the TPM to encrypt the symmetric keys and other
global secrets before saving them to disk.

Signed-off-by: Vinnie Scarlata <vincent.r.scarlata@intel.com>
tools/vtpm_manager/README
tools/vtpm_manager/Rules.mk
tools/vtpm_manager/manager/securestorage.c
tools/vtpm_manager/manager/vtpm_manager.c
tools/vtpm_manager/manager/vtpmpriv.h
tools/vtpm_manager/manager/vtsp.c
tools/vtpm_manager/manager/vtsp.h

index d01abf7e4bda3c84cd01b967fa4cbb08616cb859..f0d1e98cfbcf43fc7788050ef16ec91226851f78 100644 (file)
@@ -53,11 +53,6 @@ DUMMY_BACKEND                -> vtpm_manager listens on /tmp/in.fifo and
 
 MANUAL_DM_LAUNCH             -> Must manually launch & kill VTPMs
 
-WELL_KNOWN_SRK_AUTH          -> Rather than randomly generating the password for the SRK,
-                                use a well known value. This is necessary for sharing use
-                                of the SRK across applications. Such as VTPM and Dom0
-                                measurement software.
-
 WELL_KNOWN_OWNER_AUTH        -> Rather than randomly generating the password for the owner,
                                 use a well known value. This is useful for debugging and for
                                 poor bios which do not support clearing TPM if OwnerAuth is
index 26b44563c152e0d3ac7a26c41e0d3b8363834bd1..c7395864ac4084785cf661a4eba5835b4eba623b 100644 (file)
@@ -56,8 +56,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
 # Do not have manager launch DMs.
 #CFLAGS += -DMANUAL_DM_LAUNCH
 
-# Fixed SRK
-CFLAGS += -DWELL_KNOWN_SRK_AUTH
+# Fixed OwnerAuth
 #CFLAGS += -DWELL_KNOWN_OWNER_AUTH
 
 # TPM Hardware Device or TPM Simulator
index 5f19aa63ef301067ececc7fc8af263465ea6dbf2..4df8531c40c95c39990392fc74afb7ef033c94e8 100644 (file)
@@ -65,7 +65,7 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
   UINT32 i;
   struct pack_constbuf_t symkey_cipher32, data_cipher32;
   
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf));
   for (i=0; i< buffer_len(inbuf); i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -94,6 +94,12 @@ TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
               BSG_TPM_SIZE32_DATA, &data_cipher32);
 
   vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data));
+  for (i=0; i< buffer_len(sealed_data); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
+
   goto egress;
 
  abort_egress:
@@ -125,7 +131,7 @@ TPM_RESULT envelope_decrypt(const long         cipher_size,
 
   memset(&symkey, 0, sizeof(symkey_t));
 
-  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", cipher_size);
   for (i=0; i< cipher_size; i++)
     vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
   vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -155,6 +161,11 @@ TPM_RESULT envelope_decrypt(const long         cipher_size,
   
   // Decrypt State
   TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
+
+  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data));
+  for (i=0; i< buffer_len(unsealed_data); i++)
+    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
+  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   
   goto egress;
   
@@ -291,124 +302,175 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
   return status;
 }
 
+
 TPM_RESULT VTPM_SaveService(void) {
   TPM_RESULT status=TPM_SUCCESS;
   int fh, dmis=-1;
-  
-  BYTE *flat_global;
-  int flat_global_size, bytes_written;
+
+  BYTE *flat_boot_key, *flat_dmis, *flat_enc;
+  buffer_t clear_flat_global, enc_flat_global;
   UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
+  UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
   struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
-  
+  struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
+
   struct hashtable_itr *dmi_itr;
   VTPM_DMI_RESOURCE *dmi_res;
-  
-  UINT32 flat_global_full_size;
-  
-  // Global Values needing to be saved
-  flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
-    sizeof(UINT32) +       // storagekeysize
-    storageKeySize +       // storage key
-    hashtable_count(vtpm_globals->dmi_map) * // num DMIS
-    (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
-  
-  
-  flat_global = (BYTE *) malloc( flat_global_full_size);
-  
-  flat_global_size = BSG_PackList(flat_global, 4,
-                                 BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
-                                 BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
-                                 BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
-                                 BSG_TPM_SIZE32_DATA, &storage_key_pack);
-  
+
+  UINT32 boot_key_size, flat_dmis_size;
+
+  // Initially fill these with buffer sizes for each data type. Later fill
+  // in actual size, once flattened.
+  boot_key_size =  sizeof(UINT32) +       // bootkeysize
+                   bootKeySize;           // boot key
+
+  TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
+                                              sizeof(UINT32) +// storagekeysize
+                                              storageKeySize, NULL) ); // storage key
+
+  flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
+                   (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
+
+  flat_boot_key = (BYTE *) malloc( boot_key_size );
+  flat_enc = (BYTE *) malloc( sizeof(UINT32) );
+  flat_dmis = (BYTE *) malloc( flat_dmis_size );
+
+  boot_key_size = BSG_PackList(flat_boot_key, 1,
+                               BSG_TPM_SIZE32_DATA, &boot_key_pack);
+
+  BSG_PackList(clear_flat_global.bytes, 3,
+                BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+                BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
+                BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
+  TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
+                                &vtpm_globals->bootKey,
+                                &enc_flat_global) );
+
+  BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
+
   // Per DMI values to be saved
   if (hashtable_count(vtpm_globals->dmi_map) > 0) {
-    
+
     dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
     do {
       dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
       dmis++;
 
       // No need to save dmi0.
-      if (dmi_res->dmi_id == 0)        
-       continue;
-      
-      
-      flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
-                                       BSG_TYPE_UINT32, &dmi_res->dmi_id,
-                                       BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
-                                       BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-      
+      if (dmi_res->dmi_id == 0)
+        continue;
+
+
+      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
+                                        BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                        BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+                                        BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
     } while (hashtable_iterator_advance(dmi_itr));
   }
-  
-  //FIXME: Once we have a way to protect a TPM key, we should use it to 
-  //       encrypt this blob. BUT, unless there is a way to ensure the key is
-  //       not used by other apps, this encryption is useless.
+
   fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
   if (fh == -1) {
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  
-  if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
-    vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
+
+  if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
+       ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
+       ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
+       ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
     status = TPM_IOERROR;
     goto abort_egress;
-  }
-  vtpm_globals->DMI_table_dirty = FALSE; 
-  
+ }
+
+  vtpm_globals->DMI_table_dirty = FALSE;
+
   goto egress;
-  
+
  abort_egress:
  egress:
-  
-  free(flat_global);
+
+  free(flat_boot_key);
+  free(flat_enc);
+  buffer_free(&enc_flat_global);
+  free(flat_dmis);
   close(fh);
-  
+
   vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
   return status;
 }
 
 TPM_RESULT VTPM_LoadService(void) {
-  
+
   TPM_RESULT status=TPM_SUCCESS;
   int fh, stat_ret, dmis=0;
   long fh_size = 0, step_size;
-  BYTE *flat_global=NULL;
-  struct pack_buf_t storage_key_pack;
-  UINT32 *dmi_id_key;
-  
+  BYTE *flat_table=NULL;
+  buffer_t  unsealed_data;
+  struct pack_buf_t storage_key_pack, boot_key_pack;
+  UINT32 *dmi_id_key, enc_size;
+
   VTPM_DMI_RESOURCE *dmi_res;
   struct stat file_stat;
-  
+
+  TPM_HANDLE boot_key_handle;
+  TPM_AUTHDATA boot_usage_auth;
+  memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
+
   fh = open(STATE_FILE, O_RDONLY );
   stat_ret = fstat(fh, &file_stat);
-  if (stat_ret == 0) 
+  if (stat_ret == 0)
     fh_size = file_stat.st_size;
   else {
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  
-  flat_global = (BYTE *) malloc(fh_size);
-  
-  if ((long) read(fh, flat_global, fh_size) != fh_size ) {
+
+  flat_table = (BYTE *) malloc(fh_size);
+
+  if ((long) read(fh, flat_table, fh_size) != fh_size ) {
     status = TPM_IOERROR;
     goto abort_egress;
   }
-  
+
+  // Read Boot Key
+  step_size = BSG_UnpackList( flat_table, 2,
+                              BSG_TPM_SIZE32_DATA, &boot_key_pack,
+                              BSG_TYPE_UINT32, &enc_size);
+
+  TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
+  TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) );
+
+  //Load Boot Key
+  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+                              TPM_SRK_KEYHANDLE,
+                              &vtpm_globals->bootKeyWrap,
+                              &SRK_AUTH,
+                              &boot_key_handle,
+                              &vtpm_globals->keyAuth,
+                              &vtpm_globals->bootKey,
+                              FALSE) );
+
+  TPMTRYRETURN( envelope_decrypt(enc_size,
+                                 flat_table + step_size,
+                                 vtpm_globals->manager_tcs_handle,
+                                 boot_key_handle,
+                                 (const TPM_AUTHDATA*) &boot_usage_auth,
+                                 &unsealed_data) );
+  step_size += enc_size;
+
   // Global Values needing to be saved
-  step_size = BSG_UnpackList( flat_global, 4,
-                             BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
-                             BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
-                             BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
-                             BSG_TPM_SIZE32_DATA, &storage_key_pack);
-  
+  BSG_UnpackList( unsealed_data.bytes, 3,
+                  BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
+                  BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
+                  BSG_TPM_SIZE32_DATA, &storage_key_pack);
+
   TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
   TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
-  
+
   // Per DMI values to be saved
   while ( step_size < fh_size ){
     if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
@@ -417,35 +479,38 @@ TPM_RESULT VTPM_LoadService(void) {
     } else {
       dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
       dmis++;
-      
+
       dmi_res->connected = FALSE;
-      
-      step_size += BSG_UnpackList(flat_global + step_size, 3,
-                                 BSG_TYPE_UINT32, &dmi_res->dmi_id, 
-                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
-                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
-      
+
+      step_size += BSG_UnpackList(flat_table + step_size, 3,
+                                 BSG_TYPE_UINT32, &dmi_res->dmi_id,
+                                 BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
+                                 BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
+
       // install into map
       dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
       *dmi_id_key = dmi_res->dmi_id;
       if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
-       status = TPM_FAIL;
-       goto abort_egress;
+        status = TPM_FAIL;
+        goto abort_egress;
       }
-      
+
     }
-    
+
   }
-  
+
   vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
   goto egress;
-  
+
  abort_egress:
   vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
  egress:
-  
-  free(flat_global);
+
+  free(flat_table);
   close(fh);
-  
+
+  // TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
+
   return status;
 }
+
index 48143fbc3bd3e8e4b117b52ebc1c67385eb6a0f4..c9eda0440c6f06b9dcc7fd4f2d8aceae69c6e7ba 100644 (file)
@@ -74,16 +74,15 @@ VTPM_GLOBALS *vtpm_globals=NULL;
 #endif
 
 // --------------------------- Well Known Auths --------------------------
-#ifdef WELL_KNOWN_SRK_AUTH
-static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-#endif
 
 #ifdef WELL_KNOWN_OWNER_AUTH
 static BYTE FIXED_OWNER_AUTH[20] =  {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                                   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 #endif
-                                  
+
+
 // -------------------------- Hash table functions --------------------
 
 static unsigned int hashfunc32(void *ky) {
@@ -100,13 +99,7 @@ TPM_RESULT VTPM_Create_Service(){
   
   TPM_RESULT status = TPM_SUCCESS;
   
-  // Generate Auth's for SRK & Owner
-#ifdef WELL_KNOWN_SRK_AUTH 
-  memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
-#else    
-  Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );  
-#endif
-  
+  // Generate Auth for Owner
 #ifdef WELL_KNOWN_OWNER_AUTH 
   memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
 #else    
@@ -116,14 +109,14 @@ TPM_RESULT VTPM_Create_Service(){
   // Take Owership of TPM
   CRYPTO_INFO ek_cryptoInfo;
   
-  vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
   status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
   
   // If we can read PubEK then there is no owner and we should take it.
   if (status == TPM_SUCCESS) { 
+    vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
     TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
                                    (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 
-                                   (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                                   &SRK_AUTH,
                                    &ek_cryptoInfo,
                                    &vtpm_globals->keyAuth)); 
   
@@ -142,7 +135,7 @@ TPM_RESULT VTPM_Create_Service(){
   TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
                          TPM_ET_KEYHANDLE,
                          TPM_SRK_KEYHANDLE, 
-                         (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                         &SRK_AUTH,
                          &sharedsecret, 
                          &osap) ); 
 
@@ -157,8 +150,43 @@ TPM_RESULT VTPM_Create_Service(){
                                    &vtpm_globals->storageKeyWrap,
                                    &osap) );
   
-  vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
+  // Generate boot key's auth
+  Crypto_GetRandom(  &vtpm_globals->storage_key_usage_auth, 
+                    sizeof(TPM_AUTHDATA) );
   
+  TPM_AUTHDATA bootKeyWrapAuth;
+  memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
+  
+  TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
+                         TPM_ET_KEYHANDLE,
+                         TPM_SRK_KEYHANDLE, 
+                         &SRK_AUTH,
+                         &sharedsecret, 
+                         &osap) ); 
+
+  osap.fContinueAuthSession = FALSE;
+  // FIXME: This key protects the global secrets on disk. It should use TPM
+  //        PCR bindings to limit its use to legit configurations.
+  //        Current binds are open, implying a Trusted VM contains this code.
+  //        If this VM is not Trusted, use measurement and PCR bindings.
+  TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
+                                   TPM_KEY_BIND,
+                                   (const TPM_AUTHDATA*)&bootKeyWrapAuth,
+                                   TPM_SRK_KEYHANDLE, 
+                                   (const TPM_AUTHDATA*)&sharedsecret,
+                                   &vtpm_globals->bootKeyWrap,
+                                   &osap) );
+
+  // Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM
+  TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
+                              TPM_SRK_KEYHANDLE,
+                              &vtpm_globals->bootKeyWrap,
+                              NULL,
+                              NULL,
+                              NULL,
+                              &vtpm_globals->bootKey,
+                              TRUE ) );
   goto egress;
   
  abort_egress:
@@ -278,24 +306,26 @@ void *VTPM_Service_Handler(void *threadTypePtr){
 #endif
 
     // Check status of rx_fh. If necessary attempt to re-open it.    
+    char* s = NULL;
     if (*rx_fh < 0) {
 #ifdef VTPM_MULTI_VM
-      *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+      s = VTPM_BE_DEV;
 #else
       if (threadType == BE_LISTENER_THREAD) 
   #ifdef DUMMY_BACKEND
-       *rx_fh = open("/tmp/in.fifo", O_RDWR);
+       s = "/tmp/in.fifo";
   #else
-        *rx_fh = open(VTPM_BE_DEV, O_RDWR);
+      s = VTPM_BE_DEV;
   #endif
       else  // DMI Listener   
-       *rx_fh = open(VTPM_RX_FIFO, O_RDWR);
+       s = VTPM_RX_FIFO;
+      *rx_fh = open(s, O_RDWR);
 #endif    
     }
     
     // Respond to failures to open rx_fh
     if (*rx_fh < 0) {
-      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
+      vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
 #ifdef VTPM_MULTI_VM
       return TPM_IOERROR; 
 #else
@@ -713,7 +743,7 @@ void *VTPM_Service_Handler(void *threadTypePtr){
 
 ///////////////////////////////////////////////////////////////////////////////
 TPM_RESULT VTPM_Init_Service() {
-  TPM_RESULT status = TPM_FAIL;   
+  TPM_RESULT status = TPM_FAIL, serviceStatus;   
   BYTE *randomsead;
   UINT32 randomsize;
 
@@ -737,7 +767,7 @@ TPM_RESULT VTPM_Init_Service() {
   
   // Create new TCS Object
   vtpm_globals->manager_tcs_handle = 0;
-  
   TPMTRYRETURN(TCS_create());
   
   // Create TCS Context for service
@@ -756,17 +786,24 @@ TPM_RESULT VTPM_Init_Service() {
   vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
 
        // If failed, create new Service.
-  if (VTPM_LoadService() != TPM_SUCCESS)
+  serviceStatus = VTPM_LoadService();
+  if (serviceStatus == TPM_IOERROR) {
+    vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n");
     TPMTRYRETURN( VTPM_Create_Service() );    
+  } else if (serviceStatus != TPM_SUCCESS) {
+    vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
+    exit(1);
+  }
 
   //Load Storage Key 
   TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
                              TPM_SRK_KEYHANDLE,
                              &vtpm_globals->storageKeyWrap,
-                             (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
+                             &SRK_AUTH,
                              &vtpm_globals->storageKeyHandle,
                              &vtpm_globals->keyAuth,
-                             &vtpm_globals->storageKey) );
+                             &vtpm_globals->storageKey,
+                              FALSE ) );
 
   // Create entry for Dom0 for control messages
   TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
@@ -797,12 +834,11 @@ void VTPM_Stop_Service() {
                free (dmi_itr);
   }
   
-       
-  TCS_CloseContext(vtpm_globals->manager_tcs_handle);
-  
-  if ( (vtpm_globals->DMI_table_dirty) &&
-       (VTPM_SaveService() != TPM_SUCCESS) )
+  if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
     vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
+
+  TCS_CloseContext(vtpm_globals->manager_tcs_handle);
+  TCS_destroy();
   
   hashtable_destroy(vtpm_globals->dmi_map, 1);
   free(vtpm_globals);
index bb613aec2cbc357f7d5233d9de03728141c8e695..2f8c2ebc679a3b0aed54b6fda42add44b0d2ae6a 100644 (file)
@@ -108,6 +108,7 @@ typedef struct tdVTPM_GLOBALS {
   TCS_CONTEXT_HANDLE  manager_tcs_handle;     // TCS Handle used by manager
   TPM_HANDLE          storageKeyHandle;       // Key used by persistent store
   CRYPTO_INFO         storageKey;             // For software encryption
+  CRYPTO_INFO         bootKey;                // For saving table
   TCS_AUTH            keyAuth;                // OIAP session for storageKey 
   BOOL                DMI_table_dirty;        // Indicates that a command
                                               // has updated the DMI table
@@ -115,15 +116,17 @@ typedef struct tdVTPM_GLOBALS {
     
   // Persistent Data
   TPM_AUTHDATA        owner_usage_auth;       // OwnerAuth of real TPM
-  TPM_AUTHDATA        srk_usage_auth;         // SRK Auth of real TPM    
   buffer_t            storageKeyWrap;         // Wrapped copy of storageKey
-
+  TPM_AUTHDATA        srk_usage_auth;
   TPM_AUTHDATA        storage_key_usage_auth; 
-    
+
+  buffer_t            bootKeyWrap;            // Wrapped copy of boot key 
+
 }VTPM_GLOBALS;
 
-//Global dmi map
-extern VTPM_GLOBALS *vtpm_globals;
+// --------------------------- Global Values --------------------------
+extern VTPM_GLOBALS *vtpm_globals;   // Key info and DMI states
+extern const TPM_AUTHDATA SRK_AUTH;  // SRK Well Known Auth Value
 
 // ********************** Command Handler Prototypes ***********************
 TPM_RESULT VTPM_Handle_Load_NVM(       VTPM_DMI_RESOURCE *myDMI, 
index b6f82e4b3a8329eaf602943b24cfb097b91031db..17c3335923dfbe01782a951dbf8edd70c13aa4e0 100644 (file)
@@ -563,63 +563,69 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
                         const TPM_AUTHDATA          *parentAuth,
                         TPM_HANDLE                  *newKeyHandle,
                         TCS_AUTH                    *auth,
-                        CRYPTO_INFO                 *cryptoinfo /*= NULL*/) {
+                        CRYPTO_INFO                 *cryptoinfo,
+                        const BOOL                  skipTPMLoad) { 
   
   
-  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
+  vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory"));
   
   TPM_RESULT status = TPM_SUCCESS;
   TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
-  
-  BYTE *paramText;        // Digest to make Auth.
+
+  BYTE *paramText=NULL;        // Digest to make Auth.
   UINT32 paramTextSize;
+
+  // SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it
+  if (! skipTPMLoad) { 
   
-  if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
-      (newKeyHandle==NULL) || (auth==NULL)) {
-    status = TPM_BAD_PARAMETER;
-    goto abort_egress;
-  }
+    if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 
+        (newKeyHandle==NULL) || (auth==NULL)) {
+      status = TPM_BAD_PARAMETER;
+      goto abort_egress;
+    }
   
-  // Generate Extra TCS Parameters
-  TPM_HANDLE phKeyHMAC;
+    // Generate Extra TCS Parameters
+    TPM_HANDLE phKeyHMAC;
   
-  // Generate HMAC
-  Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
+    // Generate HMAC
+    Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
   
-  paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
+    paramText = (BYTE *) malloc(sizeof(BYTE) *  TCPA_MAX_BUFFER_LENGTH);
   
-  paramTextSize = BSG_PackList(paramText, 1,
-                              BSG_TPM_COMMAND_CODE, &command);
+    paramTextSize = BSG_PackList(paramText, 1,
+                                BSG_TPM_COMMAND_CODE, &command);
   
-  memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
-  paramTextSize += buffer_len(rgbWrappedKeyBlob);
+    memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
+    paramTextSize += buffer_len(rgbWrappedKeyBlob);
   
-  TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
+    TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
                              parentAuth, auth) );
   
-  // Call TCS
-  TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
-                                    hUnwrappingKey,
-                                    buffer_len(rgbWrappedKeyBlob),
-                                    rgbWrappedKeyBlob->bytes,
-                                    auth,
-                                    newKeyHandle,
-                                    &phKeyHMAC) );
-  
-  // Verify Auth
-  paramTextSize = BSG_PackList(paramText, 3,
-                              BSG_TPM_RESULT, &status,
-                              BSG_TPM_COMMAND_CODE, &command,
-                              BSG_TPM_HANDLE, newKeyHandle);
-  
-  TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
-                           parentAuth, auth, 
-                           hContext) );
-  
-  // Unpack/return key structure
+    // Call TCS
+    TPMTRYRETURN( TCSP_LoadKeyByBlob(  hContext,
+                                      hUnwrappingKey,
+                                      buffer_len(rgbWrappedKeyBlob),
+                                      rgbWrappedKeyBlob->bytes,
+                                      auth,
+                                      newKeyHandle,
+                                      &phKeyHMAC) );
+  
+    // Verify Auth
+    paramTextSize = BSG_PackList(paramText, 3,
+                                BSG_TPM_RESULT, &status,
+                                BSG_TPM_COMMAND_CODE, &command,
+                                BSG_TPM_HANDLE, newKeyHandle);
+  
+    TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
+                             parentAuth, auth, 
+                             hContext) );
+  } 
+  
+  // Build cryptoinfo structure for software crypto function. 
   if (cryptoinfo != NULL) {
     TPM_KEY newKey;
     
+    // Unpack/return key structure
     BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
     TPM_RSA_KEY_PARMS rsaKeyParms;
     
index ddae64e4830283362cac102055e934a016bbc6a9..93f22d34e49111c317282215668c2e0c5ea01626 100644 (file)
@@ -86,7 +86,8 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE    hContext,
                         const TPM_AUTHDATA          *parentAuth,
                         TPM_HANDLE                  *newKeyHandle,
                         TCS_AUTH                    *pAuth,
-                        CRYPTO_INFO                 *cryptoinfo);
+                        CRYPTO_INFO                 *cryptoinfo,
+                        const BOOL                  skipTPMLoad);
 
 TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE    hContext,
                         const TPM_KEY_HANDLE        key_handle,